package roborally;

import be.kuleuven.cs.som.annotate.Basic;
import be.kuleuven.cs.som.annotate.Raw;
import be.kuleuven.cs.som.annotate.Value;

/**
 * A class of weight, this class represents the weight of objects.
 * 
 * @version  2.90
 * @author   Michiel Ruelens & Dieter Naten
 */
@Value
class Weight {

	private final int numeral;
	private final WeightUnit unit;

	/**
     * Initialize the new battery with given initialEnergy and weight.
     * 
     * @param numeral
     * 		  The numeral value of the new weight
     * @param unit
     * 		  The unit of the new weight
     * @post  | (new this).getWeight() == weight
     * @post  | (new this).getUnit() == unit
     */
	@Raw
	public Weight(int numeral, WeightUnit unit){
		int resultNumeral = numeral;
		WeightUnit resultUnit = unit;
		if(!isValidWeight(numeral,unit)){
			System.out.println("That weight is invalid. Unable to properly continue.");
			resultNumeral = 0;
			resultUnit = null;
		}
		this.numeral = resultNumeral;
		this.unit = resultUnit;
	}
	
	/**
	 * Get the numeric value of this weight object.
	 */
	@Basic
	public int getNumeral(){
		return numeral;
	}
	
	/**
	 * Get the unit of this weight object.
	 */
	@Basic
	public WeightUnit getUnit(){
		return unit;
	}
	
	/**
	 * This method controls if a given weight is valid.
	 * 
	 * @param  numeral
	 * 		   The numeral of the weight that has to be verified
	 * @param  unit
	 * 		   The unit of the weight that has to be verified
	 * @return | result ==
	 * 		   | ((numeral>0) && (numeral<Integer.MAX_VALUE) && (unit instanceof Unit))
	 */
	public static boolean isValidWeight(int numeral ,WeightUnit unit){
		return ((numeral>0) && (numeral<Integer.MAX_VALUE) && (unit instanceof WeightUnit));
	}
	
	/**
	 * Converts this weight to another unit. Beware that these conversions might round off the exact value.
	 * 
	 * @param 	other
	 * 			The unit that is being converted to.
	 * @return	| new Weight((numeral*unit.toUnitFactor(other),other)
	 */
	public Weight toWeightUnit(WeightUnit other){
		int resultNumeral = numeral;
		WeightUnit resultUnit = other;
		double factor = unit.toWeightUnitFactor(other);
		resultNumeral = (int) (numeral*factor);
		return new Weight(resultNumeral,resultUnit);
	}
}
